/**
 * 
 */
package com.jiang.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

import com.jiang.utils.DBConnectionUtils;

/**
 * @author Administrator
 * @动态代理，因为有太多的子类了，不方便用静态代理。
 *                           <li>实现异常的统一处理</li>
 *                           <li>统一的关闭数据库连接</li>
 *                           <li>针对性的事务回滚处理</li>
 */
public class ServiceProxy implements InvocationHandler {

	// 真实类
	private Object target;

	/**
	 * @代理类绑定真实类, 并且生成代理对象
	 * 
	 * @param obj
	 * @return
	 */
	public Object bind(Object obj) {

		this.target = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}

	/**
	 * 动态代理的真正处理回调函数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// 1. 处理异常 2. 处理连接 3. 处理回滚
		// 因为现在的连接都是在池子中获取，所以我们拿了就行了，没有就会创建塞进去，以后dao也拿的是同一个
		// 因为都在同一个线程中处理。(一个请求中的完成)
		Object result = null;
		Connection conn = DBConnectionUtils.getConnection();
		try {
			
			// 根据特定的方法来决定是否事务回滚
			/**
			 * <li>注意方法的定义规范，使用doCreate() doRemove() doFind() doGet() doUpdate()</li>
			 * <li>在业务层使用save() delete() find() get() update()</li>
			 */
			String methodName = method.getName();
			if (methodName.startsWith("save") || methodName.startsWith("update") || methodName.startsWith("delete")
					|| methodName.startsWith("remove") || methodName.startsWith("removeBatch")) {
				conn.setAutoCommit(false);
				result = method.invoke(target, args);
				conn.commit();
			}else{
				result = method.invoke(this.target, args);
			}

		} catch (Exception e) {
			conn.rollback();
			e.printStackTrace();
			throw e;
		} finally {
			DBConnectionUtils.close();
		}

		return result;
	}

}
